using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Microsoft.WowAddonStudio.FrameXml.Components;
using Microsoft.WowAddonStudio.FrameXml.Components.Support;
using Microsoft.WowAddonStudio.FrameXml.Components.Tests;
using Microsoft.WowAddonStudio.FrameXml.Design.Serialization;
using Microsoft.WowAddonStudio.FrameXml.Serialization.LayoutFrames;
using Microsoft.WowAddonStudio.FrameXml.Services;
using Microsoft.WowAddonStudio.Tests.Common.Mocks;

using NUnit.Framework;

namespace Microsoft.WowAddonStudio.FrameXml.Design.Tests.Serialization
{
	[TestFixture]
	public class DesignerSerializationTest : SerializationTestBase
	{
		private FrameXmlDesignerSerializationService designerSerializationService;
		private FrameXmlComponentSerializationService componentSerializationService;
		

		#region SetUp

		[TestFixtureSetUp]
		public void TestFixtureSetUp()
		{
			locator = new SimpleTestServiceLocator();
			serializer = new FrameXmlRuntimeSerializer();
		}

		[SetUp]
		public void SetUp()
		{
			componentSerializationService = new FrameXmlComponentSerializationService(locator, serializer);
			var factory = new FrameXmlComponentFactory(new ReflectionComponentActivator(),locator,locator);

			SimpleTestServiceLocator.Register<IFrameXmlComponentSerializationService>(componentSerializationService);
			SimpleTestServiceLocator.Register(factory);

			designerSerializationService = new FrameXmlDesignerSerializationService(locator, locator);
		}

		#endregion

		#region TearDown

		[TearDown]
		public void TearDown()
		{
			SimpleTestServiceLocator.UnRegister<IFrameXmlComponentSerializationService>();
			SimpleTestServiceLocator.UnRegister<FrameXmlComponentFactory>();
			
		}

		#endregion

		#region Tests

		/// <summary>
		/// Tests the serialize.
		/// </summary>
		[Test(Description = "")]
		public void Test_SerializeDeSerialize()
		{
			var controls = new List<Control>
			               	{
			               		new FrameControl(new Frame {Name = "TestControl"})
			               			{Name = "TestControl"}
			               	};
			//Serialize control
			var serializedResult = designerSerializationService.Serialize(controls);

			Assert.IsNotNull(serializedResult);
			Assert.IsInstanceOfType(typeof(FrameXmlSerializationStore), serializedResult);
			var serializationStore = serializedResult as FrameXmlSerializationStore;
			Assert.IsNotNull(serializationStore);
			Assert.IsNotNull(serializationStore.Errors);
			Assert.AreEqual(0, serializationStore.Errors.Count);

			//Deserialize control
			var deserializedResult = designerSerializationService.Deserialize(serializationStore);

			Assert.IsNotNull(deserializedResult);
			Assert.AreEqual(1, deserializedResult.Count);
			var control = deserializedResult.OfType<Control>().SingleOrDefault();
			Assert.IsNotNull(control);
			Assert.IsInstanceOfType(typeof(FrameControl), control);
			Assert.IsNotNull(((FrameControl)control).LayoutFrame);
			Assert.IsInstanceOfType(typeof(Frame), ((FrameControl)control).LayoutFrame);
			Assert.AreEqual("TestControl", ((FrameControl)control).LayoutFrame.Name);
		}

		[Test(Description = "")]
		[ExpectedException(typeof(BadSerializationObjectException))]
		public void Test_DeSerializeFailed()
		{
			var serializationStore = new object();
			designerSerializationService.Deserialize(serializationStore);
		}

		/// <summary>
		/// Tests the designer serialization init failed.
		/// </summary>
		[Test(Description = "")]
		[ExpectedException(typeof (MissingServiceException))]
		public void Test_DesignerSerializationInitFailed()
		{
			SimpleTestServiceLocator.UnRegister<IFrameXmlComponentSerializationService>();
			designerSerializationService = new FrameXmlDesignerSerializationService(locator, locator);
		}

		#endregion
	}
}